package org.luosl.webmagicx.monitor.action

import java.util.concurrent.ConcurrentHashMap

import org.luosl.webmagicx.monitor.{HttpSpiderMonitor, JsonResult, MonitorCell}
import play.api.libs.json._
import akka.http.scaladsl.model._
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.Route
import org.luosl.webmagicx.SpiderCell
import org.luosl.webmagicx.utils.DateUtils
import org.luosl.webmagicx.conf._



case class SpiderAction(monitor:HttpSpiderMonitor) {

  private val monitorCellMap:ConcurrentHashMap[String,MonitorCell] = monitor.monitorCellMap

  /**
    * 获取爬虫运行状态
    * @param id id
    * @return
    */
  def spiderState(id:String):Route = {
    val result:JsonResult = Option(monitorCellMap.get(id)) match {
      case Some(cell) =>
        val (sl, pl, sc, hls, pipels) = (cell.spiderListener, cell.processorListener,
          cell.spiderCell.sc, cell.handlerListeners, cell.pipelineListeners)
        val js:JsObject = Json.obj(
          // 爬虫基本信息
          "id" -> cell.spiderCell.id,
          "desc" -> sc.desc,
          "startTime" -> DateUtils.dateFormat(sl.startTime),
          "runTime" -> sl.runTime,
          "taskType" -> sc.taskType,
          "status" -> cell.spiderCell.status().toString,
          "threadNum" -> sc.attribute.threadNum,
          "totalRequestsCount" -> sl.totalAndLeftRequestCount._1,
          "leftRequestsCount" -> sl.totalAndLeftRequestCount._2,
          "successCount" -> sl.successCount,
          "errorCount" -> sl.errorCount,
          // processor 信息
          "processor" -> Json.obj(
            "name" -> pl.name,
            "successCount" -> pl.successCount,
            "errorCount" -> pl.errorCount,
            "skipeCount" -> pl.skipCount
          ),
          // handler 信息
          "handlers" -> hls.map{ hl=>
            Json.obj(
              "name" -> hl.name,
              "successCount" -> hl.successCount,
              "errorCount" -> hl.errorCount,
              "skipeCount" -> hl.skipCount
            )
          },
          "pipelines" -> pipels.map{ pl=>
            Json.obj(
              "name" -> pl.name,
              "successCount" -> pl.successCount,
              "errorCount" -> pl.errorCount,
              "skipeCount" -> pl.skipCount
            )
          }
        )
        JsonResult.success(js)
      case None => JsonResult.error(s"无效的 spiderId:$id")
    }
    complete(HttpEntity(ContentTypes.`application/json`, result.jsStr))
  }

  /**
    * 获取爬虫配置
    * @param id id
    * @return
    */
  def spiderConf(id:String):Route = {
    monitorCellMap.get(id) match {
      case null =>
        val res:JsonResult = JsonResult.error(s"无效的spiderId:$id")
        complete(HttpEntity(ContentTypes.`application/json`, res.jsStr))
      case cell =>
        val sc:SpiderConf = cell.spiderCell.sc
        complete(HttpEntity(ContentTypes.`text/xml(UTF-8)`, sc.xmlStr))
    }

  }

  /**
    * 提交一个任务
    * @param data xml配置
    * @return
    */
  def submit(data:String):Route = {
    val jsonResult:JsonResult = try{
      val sc:SpiderConf = ConfLoader.parseConf(data)
      val spiderCell:SpiderCell = SpiderCell(sc)
      val id:String = monitor.submitSpiderTask(spiderCell)
      JsonResult.success("提交成功",Json.obj("id" -> id))
    }catch {
      case e:Exception => JsonResult.error(e.getMessage)
    }
    complete(HttpEntity(ContentTypes.`application/json`, jsonResult.jsStr))
  }

  /**
    * 停止一个任务
    * @param id id
    * @return
    */
  def kill(id:String):Route = {
    val jsonResult:JsonResult = try {
      monitor.kill(id)
      JsonResult.success(s"kill [id=$id]成功")
    }catch {
      case e:Exception => JsonResult.error(s"error:${e.getMessage}")
    }
    complete(HttpEntity(ContentTypes.`application/json`, jsonResult.jsStr))
  }

}
